package top.pengdong.pictureShare.userAuth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.j2objc.annotations.AutoreleasePool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import top.pengdong.pictureShare.common.model.PageUtils;
import top.pengdong.pictureShare.common.model.Query;
import top.pengdong.pictureShare.common.model.SysConstant;
import top.pengdong.pictureShare.userAuth.dao.TAuthDao;
import top.pengdong.pictureShare.userAuth.dao.TRoleAuthDao;
import top.pengdong.pictureShare.userAuth.dao.TRoleDao;
import top.pengdong.pictureShare.userAuth.entity.TAuthEntity;
import top.pengdong.pictureShare.userAuth.entity.TRoleAuthEntity;
import top.pengdong.pictureShare.userAuth.entity.TRoleEntity;
import top.pengdong.pictureShare.userAuth.service.TAuthService;

import javax.annotation.PostConstruct;
import javax.management.relation.Role;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service("tAuthService")
public class TAuthServiceImpl extends ServiceImpl<TAuthDao, TAuthEntity> implements TAuthService {

    @Autowired
    private TRoleAuthDao tRoleAuthDao;

    @Autowired
    private TRoleDao tRoleDao;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 角色映射表
     */
    public final Map<String, Long> roles = new HashMap<>();

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<TAuthEntity> page = this.page(
                new Query<TAuthEntity>().getPage(params),
                new QueryWrapper<TAuthEntity>()
                        .eq("is_menu", 0)
                        .or()
                        .eq("is_menu", 2)
        );
        for (TAuthEntity tAuthEntity : page.getRecords()) {
            searchWithRoles(tAuthEntity);
        }
        return new PageUtils(page);
    }

    /**
     * 查询权限对应的 角色
     */
    @Override
    public void searchWithRoles(TAuthEntity tAuthEntity) {
        List<Long> roleId = tRoleAuthDao.selectList(new QueryWrapper<TRoleAuthEntity>()
                .eq("auth_id", tAuthEntity.getId())
        ).stream().map(tRoleAuthEntity -> tRoleAuthEntity.getRoleId()).collect(Collectors.toList());
        if (roleId.size() <= 0) return;
        tAuthEntity.setRoles(tRoleDao.selectBatchIds(roleId).stream()
                                .map(role -> {
                                    return SysConstant.ROLE_PREFIX + role.getName();
                                }).collect(Collectors.toList()));
    }

    /**
     * 加载名单 权限列表
     */
    @PostConstruct
    public void init() {
        log.info("加载 url 名单");
        // 加载白名单权限
        redisTemplate.delete(SysConstant.WHITE_URLS);
        List<String> whiteList =
                this.list(new QueryWrapper<TAuthEntity>().eq("is_menu", 2))
                .stream().map(auth -> {
                    return auth.getPath();
                }).collect(Collectors.toList());
        redisTemplate.opsForValue().set(SysConstant.WHITE_URLS, whiteList);

        // 加载权限列表
        redisTemplate.delete(SysConstant.OAUTH_URLS);
        List<TAuthEntity> list = this.baseMapper.selectList(new QueryWrapper<TAuthEntity>()
                .eq("is_menu", 0));
        for (TAuthEntity tAuthEntity : list) {
            searchWithRoles(tAuthEntity);
            redisTemplate.opsForHash().put(SysConstant.OAUTH_URLS, tAuthEntity.getPath(), tAuthEntity.getRoles());
        }

        // 预先加载用户角色信息
        List<TRoleEntity> roleList = tRoleDao.selectList(new QueryWrapper<TRoleEntity>().eq("status", 1));
        for (TRoleEntity role : roleList) {
            roles.put(SysConstant.ROLE_PREFIX + role.getName(), role.getId());
        }
        log.info("加载 url 名单 完成");
    }

    /**
     * 保存用户权限和角色信息
     * @param tAuth
     */
    @Override
    public void saveWithRoles(TAuthEntity tAuth) {
        this.save(tAuth);
        // 保存用户权限信息
        if (tAuth.getIsMenu() == 0) {
            for (String str : tAuth.getRoles()) {
                TRoleAuthEntity tRoleAuthEntity = new TRoleAuthEntity();
                tRoleAuthEntity.setStatus(1);
                tRoleAuthEntity.setAuthId(tAuth.getId());
                // TODO 固定了 用户角色
                tRoleAuthEntity.setRoleId(roles.get(str));

                tRoleAuthDao.insert(tRoleAuthEntity);
            }
        }
        redisTemplate.opsForHash().put(SysConstant.OAUTH_URLS, tAuth.getPath(), tAuth.getRoles());
    }
}